home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / lib / asm / lmath.s < prev    next >
Encoding:
Text File  |  1998-10-04  |  5.3 KB  |  281 lines

  1. * Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2. *
  3. * Permission is granted to anyone to use this software for any purpose
  4. * on any computer system, and to redistribute it freely, with the
  5. * following restrictions:
  6. * 1) No charge may be made other than reasonable charges for reproduction.
  7. * 2) Modified versions must be clearly marked as such.
  8. * 3) The authors are not responsible for any harmful consequences
  9. *    of using this software, even if they result from defects in it.
  10. **************************************************************************
  11. ;
  12. ; MODIFIED FOR USE WITH THE ACE BASIC COMPILER
  13. ; Copyright (C) 1998 David Benn
  14. ; This program is free software; you can redistribute it and/or
  15. ; modify it under the terms of the GNU General Public License
  16. ; as published by the Free Software Foundation; either version 2
  17. ; of the License, or (at your option) any later version.
  18. ;
  19. ; This program is distributed in the hope that it will be useful,
  20. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22. ; GNU General Public License for more details.
  23. ;
  24. ; You should have received a copy of the GNU General Public License
  25. ; along with this program; if not, write to the Free Software
  26. ; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  27. ;
  28. ; This code is used for the ACE Amiga BASIC compiler, with thanks to Sozobon.
  29. ;
  30. ; Minor modifications were necessary to accomodate the fact that ACE pushes
  31. ; operands for long division, multiplication and modulo arithmetic in reverse
  32. ; order to C. ace_ldiv and ace_lrem were later added (July 1994) to isolate
  33. ; this bletcherosity to ACE's "\" and "MOD" operators. ldiv[u] and lrem[u] 
  34. ; were then returned to their original state so as to be compatible with C 
  35. ; code linked to ACE programs (previously, operands had to be reversed in 
  36. ; such C code!). To avoid confusion, lmul and lmulu were also returned to
  37. ; their original state.
  38. ;
  39. ; Modified by: David J Benn
  40. ;      Date: 21st,22nd December 1992,
  41. ;           1st March 1993,
  42. ;           29th July 1994
  43. ;
  44.  
  45.     SECTION lmath_CODE
  46.  
  47.     PUBLIC    ace_ldiv
  48. ace_ldiv:
  49.     move.l    8(a7),d0
  50.     bpl    ace_ld1
  51.     neg.l    d0
  52. ace_ld1:
  53.     move.l    4(a7),d1
  54.     bpl    ace_ld2
  55.     neg.l    d1
  56.     eor.b    #$80,8(a7)
  57. ace_ld2:
  58.     jsr    i_ldiv        /* d0 = d0/d1 */
  59.     tst.b    8(a7)
  60.     bpl    ace_ld3
  61.     neg.l    d0
  62. ace_ld3:
  63.     rts
  64.  
  65.     PUBLIC    ldiv
  66. ldiv:
  67.     move.l    4(a7),d0
  68.     bpl    ld1
  69.     neg.l    d0
  70. ld1:
  71.     move.l    8(a7),d1
  72.     bpl    ld2
  73.     neg.l    d1
  74.     eor.b    #$80,4(a7)
  75. ld2:
  76.     jsr    i_ldiv        /* d0 = d0/d1 */
  77.     tst.b    4(a7)
  78.     bpl    ld3
  79.     neg.l    d0
  80. ld3:
  81.     rts
  82.  
  83.     PUBLIC    lmul
  84. lmul:
  85.     move.l    4(a7),d0
  86.     bpl    lm1
  87.     neg.l    d0
  88. lm1:
  89.     move.l    8(a7),d1
  90.     bpl    lm2
  91.     neg.l    d1
  92.     eor.b    #$80,4(a7)
  93. lm2:
  94.     jsr    i_lmul        /* d0 = d0*d1 */
  95.     tst.b    4(a7)
  96.     bpl    lm3
  97.     neg.l    d0
  98. lm3:
  99.     rts
  100.  
  101.     PUBLIC    ace_lrem
  102. ace_lrem:
  103.     move.l    8(a7),d0
  104.     bpl    ace_lr1
  105.     neg.l    d0
  106. ace_lr1:
  107.     move.l    4(a7),d1
  108.     bpl    ace_lr2
  109.     neg.l    d1
  110. ace_lr2:
  111.     jsr    i_ldiv        /* d1 = d0%d1 */
  112.     move.l    d1,d0
  113.     tst.b    8(a7)
  114.     bpl    ace_lr3
  115.     neg.l    d0
  116. ace_lr3:
  117.     rts
  118.  
  119.     PUBLIC    lrem
  120. lrem:
  121.     move.l    4(a7),d0
  122.     bpl    lr1
  123.     neg.l    d0
  124. lr1:
  125.     move.l    8(a7),d1
  126.     bpl    lr2
  127.     neg.l    d1
  128. lr2:
  129.     jsr    i_ldiv        /* d1 = d0%d1 */
  130.     move.l    d1,d0
  131.     tst.b    4(a7)
  132.     bpl    lr3
  133.     neg.l    d0
  134. lr3:
  135.     rts
  136.  
  137.     PUBLIC    ldivu
  138. ldivu:
  139.     move.l    4(a7),d0
  140.     move.l    8(a7),d1
  141.     jsr    i_ldiv
  142.     rts
  143.  
  144.     PUBLIC    lmulu
  145. lmulu:
  146.     move.l    4(a7),d0
  147.     move.l    8(a7),d1
  148.     jsr    i_lmul
  149.     rts
  150.  
  151.     PUBLIC    lremu
  152. lremu:
  153.     move.l    4(a7),d0
  154.     move.l    8(a7),d1
  155.     jsr    i_ldiv
  156.     move.l    d1,d0
  157.     rts
  158.  
  159. * A in d0, B in d1, return A*B in d0
  160. i_lmul:
  161.     move.l    d3,a2        /* save d3 */
  162.     move.w    d1,d2
  163.     mulu    d0,d2        /* d2 = Al * Bl */
  164.  
  165.     move.l    d1,d3
  166.     swap    d3
  167.     mulu    d0,d3        /* d3 = Al * Bh */
  168.  
  169.     swap    d0
  170.     mulu    d1,d0        /* d0 = Ah * Bl */
  171.  
  172.     add.l    d3,d0        /* d0 = (Ah*Bl + Al*Bh) */
  173.     swap    d0
  174.     clr.w    d0        /* d0 = (Ah*Bl + Al*Bh) << 16 */
  175.  
  176.     add.l    d2,d0        /* d0 = A*B */
  177.     move.l    a2,d3        /* restore d3 */
  178.     rts
  179.  
  180. *A in d0, B in d1, return A/B in d0, A%B in d1
  181. i_ldiv:
  182.     tst.l    d1
  183.     bne    nz1
  184.  
  185. *    divide by zero
  186.     divu    #0,d0        /* cause trap */
  187.     move.l    #$80000000,d0
  188.     move.l    d0,d1
  189.     rts
  190. nz1:
  191.     move.l    d3,a2        /* save d3 */
  192.     cmp.l    d1,d0
  193.     bhi    norm
  194.     beq    is1
  195. *    A<B, so ret 0, rem A
  196.     move.l    d0,d1
  197.     clr.l    d0
  198.     move.l    a2,d3        /* restore d3 */
  199.     rts
  200. *    A==B, so ret 1, rem 0
  201. is1:
  202.     moveq.l    #1,d0
  203.     clr.l    d1
  204.     move.l    a2,d3        /* restore d3 */
  205.     rts
  206. *    A>B and B is not 0
  207. norm:
  208.     cmp.l    #1,d1
  209.     bne    not1
  210. *    B==1, so ret A, rem 0
  211.     clr.l    d1
  212.     move.l    a2,d3        /* restore d3 */
  213.     rts
  214. *  check for A short (implies B short also)
  215. not1:
  216.     cmp.l    #$ffff,d0
  217.     bhi    slow
  218. *  A short and B short -- use 'divu'
  219.     divu    d1,d0        /* d0 = REM:ANS */
  220.     swap    d0        /* d0 = ANS:REM */
  221.     clr.l    d1
  222.     move.w    d0,d1        /* d1 = REM */
  223.     clr.w    d0
  224.     swap    d0
  225.     move.l    a2,d3        /* restore d3 */
  226.     rts
  227. * check for B short
  228. slow:
  229.     cmp.l    #$ffff,d1
  230.     bhi    slower
  231. * A long and B short -- use special stuff from gnu
  232.     move.l    d0,d2
  233.     clr.w    d2
  234.     swap    d2
  235.     divu    d1,d2        /* d2 = REM:ANS of Ahi/B */
  236.     clr.l    d3
  237.     move.w    d2,d3        /* d3 = Ahi/B */
  238.     swap    d3
  239.  
  240.     move.w    d0,d2        /* d2 = REM << 16 + Alo */
  241.     divu    d1,d2        /* d2 = REM:ANS of stuff/B */
  242.  
  243.     move.l    d2,d1
  244.     clr.w    d1
  245.     swap    d1        /* d1 = REM */
  246.  
  247.     clr.l    d0
  248.     move.w    d2,d0
  249.     add.l    d3,d0        /* d0 = ANS */
  250.     move.l    a2,d3        /* restore d3 */
  251.     rts
  252. *    A>B, B > 1
  253. slower:
  254.     move.l    #1,d2
  255.     clr.l    d3
  256. moreadj:
  257.     cmp.l    d0,d1
  258.     bhi    adj        /* Was bhs - Jal */
  259.     beq    adj
  260.     add.l    d2,d2
  261.     add.l    d1,d1
  262.     bpl    moreadj
  263. * we shifted B until its >A or sign bit set
  264. * we shifted #1 (d2) along with it
  265. adj:
  266.     cmp.l    d0,d1
  267.     bhi    ltuns
  268.     or.l    d2,d3
  269.     sub.l    d1,d0
  270. ltuns:
  271.     lsr.l    #1,d1
  272.     lsr.l    #1,d2
  273.     bne    adj
  274. * d3=answer, d0=rem
  275.     move.l    d0,d1
  276.     move.l    d3,d0
  277.     move.l    a2,d3        /* restore d3 */
  278.     rts
  279.     END
  280.